package com.myhost;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;

import android.app.Service;
import android.content.Intent;
import android.os.Environment;
import android.os.IBinder;
import android.util.Log;

import com.myhost.model.Instruction;
import com.myhost.utils.Convert;
import com.myhost.utils.FileOperations;


public class HostService extends Service {

	private ServerSocket sSocket = null;
	private InputStream isSize = null;
	private OutputStream os = null;
	private Socket socket = null;
	private SendFileList sendfl = null;
	private boolean flag = true;
	private String SDPATH; 
	private FileOperations fileOper;
	private String path;
	private String name;
	
	
	@Override
	public void onCreate() {
		super.onCreate();
		Log.i("tag", "service succeed");
		SDPATH = Environment.getExternalStorageDirectory().getAbsolutePath()+File.separator;
		receiveThread receiveThread = new receiveThread();
		Thread thread = new Thread(receiveThread);
		thread.start();
	}

	@Override
	public int onStartCommand(Intent intent, int flags, int startId) {

		
//		phonePath = Environment.getExternalStorageDirectory().getAbsolutePath();
//		
//		path = intent.getStringExtra("path");
//		Log.i("tag", "intent service---->" + path);
		return super.onStartCommand(intent, flags, startId);
	}

	@Override
	public void onDestroy() {

		Log.i("tag", "service destroy");
		flag = false;
		if (socket != null) {
			try {
				Log.i("tag", "socket close onDestroy ");
				socket.close();
				socket = null;
			} catch (IOException e) {
				e.printStackTrace();
			}
		}

		if (sSocket != null) {
			try {
				Log.i("tag", "sSocketserver close onDestroy ");
				sSocket.close();
				sSocket = null;
			} catch (IOException e) {
				e.printStackTrace();
			}
		}

		super.onDestroy();
	}

	class receiveThread implements Runnable {
		public receiveThread() {
			super();
		}

		@Override
		public void run() {
			Log.i("tag", "thread start");
			try {
				sSocket = new ServerSocket(10112);
				while (flag) {
					try {
						socket = sSocket.accept();
						isSize = socket.getInputStream();
						byte[] buffer = new byte[16];
						int temp;
						isSize.read(buffer, 0, 16);
						Instruction ins = new Instruction(buffer);
						Log.i("ins", ins.toString());
						
						executeInstruction(ins);
						
					} catch (IOException e) {
						e.printStackTrace();
					} finally {
						if (isSize != null) {
							try {
								isSize.close();
								isSize = null;
							} catch (IOException e) {
								e.printStackTrace();
							}
						}

						if(os != null){
							try {
								os.close();
								os = null;
							} catch (IOException e) {
								e.printStackTrace();
							}
						}
						if (socket != null) {
							try {
								Log.i("tag", "socket close");
								socket.close();
								socket = null;
							} catch (IOException e) {
								e.printStackTrace();
							}
						}
					}

				}
			} catch (IOException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			} finally {
				if (sSocket != null) {
					try {
						Log.i("tag", "sSocketserver close");
						sSocket.close();
						sSocket = null;
					} catch (IOException e) {
						e.printStackTrace();
					}
				}
			}

		}

	}

	private void executeInstruction(Instruction ins) throws IOException{
		switch (ins.cmd) {
		case AppConstant.SHOW:
			sendfl = SendFileList.getSendFileList();
			os = socket.getOutputStream();
			if(ins.pathSize == 0){
				sendfl.send("", os, ins.nameSize);
			}else{
				sendfl.receivePathAndSend(ins.pathSize, isSize, os, ins.nameSize);
			}
			break;
		case AppConstant.SHOWOTHERDIR:
			sendfl = SendFileList.getSendFileList();
			os = socket.getOutputStream();
			sendfl.sendOtherDir(ins.pathSize, ins.nameSize, os);
			break;
		case AppConstant.SHOWOTHERFILE:
			sendfl = SendFileList.getSendFileList();
			os = socket.getOutputStream();
			sendfl.sendOtherFile(ins.pathSize, ins.nameSize, os);
			break; 
		case AppConstant.PASTEFROMPC:
			// fileOperat.isFileExist(fileName);
			fileOper = FileOperations.getFileOperations();
			byte[] pathBuffer = new byte[ins.pathSize];
			isSize.read(pathBuffer, 0, ins.pathSize);
			path = new String(pathBuffer);
			Log.i("tag", "pastefrompc path---->" + path);
			byte[] nameBuffer = new byte[ins.nameSize]; 
			isSize.read(nameBuffer, 0, ins.nameSize);
			name = new String(nameBuffer);
			Log.i("tag", "pastefrompc name---->" + name);
			os = socket.getOutputStream();
			boolean isExist = fileOper.isFileExist(SDPATH +  path + File.separator + name);
			int resultPA = 0;
			if(isExist){
				resultPA = 1;
				os.write(Convert.Int2Bytes(resultPA));
				byte[] bufferPAS = new byte[16];
				isSize.read(bufferPAS, 0, 16);
				Instruction instr = new Instruction(bufferPAS);
				if(instr.cmd == AppConstant.SUBMIT){
					fileOper.writeFileFromInput(SDPATH +  path, name,isSize);
				}
			}else{
				os.write(Convert.Int2Bytes(resultPA));
				fileOper.writeFileFromInput(SDPATH +  path, name,isSize);
			}
			break;
		case AppConstant.COPYTOPC:
			byte[] pathBufferC = new byte[ins.pathSize];
			isSize.read(pathBufferC, 0, ins.pathSize);
			path = new String(pathBufferC);
			Log.i("tag", "copytopc  path---->" + path);
			os = socket.getOutputStream();
			
			fileOper = FileOperations.getFileOperations();
			fileOper.sendFile(SDPATH + path, os);
			break;
		case AppConstant.CUT:
			fileOper = FileOperations.getFileOperations();
			byte[] pathBufferCU = new byte[ins.pathSize];
			isSize.read(pathBufferCU, 0, ins.pathSize);
			path = new String(pathBufferCU);			
			byte[] nameBufferCU = new byte[ins.nameSize]; 
			isSize.read(nameBufferCU, 0, ins.nameSize);
			name = new String(nameBufferCU);
			int result = fileOper.rename(SDPATH + path, SDPATH + name);
			os = socket.getOutputStream();
			os.write(Convert.Int2Bytes(result));
			break;
		case AppConstant.OTHERFILES:
			fileOper = FileOperations.getFileOperations();
			os = socket.getOutputStream();
			fileOper.sendOther(os);
			break;
		case AppConstant.RENAME:
			fileOper = FileOperations.getFileOperations();
			byte[] pathBufferR = new byte[ins.pathSize];
			isSize.read(pathBufferR, 0, ins.pathSize);
			path = new String(pathBufferR);
			Log.i("tag", "pastefrompc path---->" + path);
			byte[] nameBufferR = new byte[ins.nameSize]; 
			isSize.read(nameBufferR, 0, ins.nameSize);
			name = new String(nameBufferR);
			int resultR = fileOper.rename(SDPATH + path, SDPATH + name);
			os = socket.getOutputStream();
			os.write(Convert.Int2Bytes(resultR));
		case AppConstant.ADNROIDTOANDROID:
			fileOper = FileOperations.getFileOperations();
			byte[] pathBufferA = new byte[ins.pathSize];
			isSize.read(pathBufferA, 0, ins.pathSize);
			path = new String(pathBufferA);			
			byte[] nameBufferA = new byte[ins.nameSize]; 
			isSize.read(nameBufferA, 0, ins.nameSize);
			name = new String(nameBufferA);
			
			Log.i("tag", "ADNROIDTOANDROID path---->" + path + "       ADNROIDTOANDROID  two path--->" + name);
			int resultA = fileOper.androidToAndroid(SDPATH + path,SDPATH + name);
			os = socket.getOutputStream();
			os.write(Convert.Int2Bytes(resultA));
		case AppConstant.DELETE:
			fileOper = FileOperations.getFileOperations();
			byte[] pathBufferD = new byte[ins.pathSize];
			isSize.read(pathBufferD, 0, ins.pathSize);
			path = new String(pathBufferD);	
			fileOper.deleteFile(new File(SDPATH + path));
			os = socket.getOutputStream();
			os.write(Convert.Int2Bytes(0));
		case AppConstant.NEW:
			fileOper = FileOperations.getFileOperations();
			byte[] pathBufferN = new byte[ins.pathSize];
			isSize.read(pathBufferN, 0, ins.pathSize);
			path = new String(pathBufferN);	
			boolean boolResult = fileOper.creatDirectory(SDPATH + path);
			int resultN = 0;
			if(!boolResult){
				resultN = 1;
			}
			os = socket.getOutputStream();
			os.write(Convert.Int2Bytes(resultN));
		default:
			break;
		}
	}
	
	private void receiveFile(Instruction ins){
		try {
			byte[] pathBuffer = new byte[ins.pathSize];
			isSize.read(pathBuffer, 0, ins.pathSize);
			String path = new String(pathBuffer);
			byte[] nameBuffer = new byte[ins.nameSize];
			isSize.read(nameBuffer, 0, ins.nameSize);
			String name = new String(nameBuffer);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	@Override
	public IBinder onBind(Intent arg0) {
		// TODO Auto-generated method stub
		return null;
	}
	
//    private static byte[] Int2Bytes(int n) {  
//        byte[] b = new byte[4];  
//        b[3] = (byte) (n & 0xff);  
//        b[2] = (byte) (n >> 8 & 0xff);  
//        b[1] = (byte) (n >> 16 & 0xff);  
//        b[0] = (byte) (n >> 24 & 0xff);  
//        return b;  
//    }  

}
